
require 'json'
require 'ftools'

module DrunkenMaster
  class FileStorage

    attr_accessor :folder

    def put key, revision, data
      slot = slot(key, revision)
      File.open(slot, 'w+') { |file|
        file.write data
      }
      File.copy(slot, slot(key, 'HEAD'))
    end

    def get key, revision = 'HEAD'
      content = nil
      file = slot(key, revision)
      next if key[0,1] == '.'
      if File.exist? file
        File.open(file) do |f|
          content = f.read
        end
      else
        raise "No file at #{file}."
      end
      content
    end

    def list main_key = '.'
      raise 'Set the folder first!' unless @folder
      raise "This is not a folder: '#{@folder}'." unless File.directory?(@folder)
      {}.tap do |list|
        Dir.foreach(File.join(@folder, main_key)) do |key|
          next if key[0,1] == '.'
          begin
            list[key] = get(key, 'HEAD')
          rescue
            e = Magic.wrap("Problem reading key '#{key}'.", $!)
            warn e.message + "\n" + e.backtrace.join
          end
        end
      end
    end

    def remove_all
      remove_under(@folder)
    end

  private

    def remove_under folder
      Dir.foreach(folder) do |filename|
        next if filename[0,1] == '.'
        file = File.join(folder, filename)
        if File.directory?(file)
          remove_under file
          Dir.unlink(file)
        else
          File.unlink(file)
        end
      end
    end

    def slot uuid, revision
      File.join(r_mkdir(uuid), revision.to_s+'.txt')
    end

    # Recursive mkdir
    def r_mkdir dir
      path = @folder
      File.split(dir).each do |folder_name|
        path = File.join(path, folder_name)
        unless File.directory?(path)
          Dir.mkdir(path)
        end
      end
      path
    end


  end
end